package com.itheima.sc.service.ums;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.itheima.sc.api.ums.*;
import com.itheima.sc.dto.UpdatePasswordDto;
import com.itheima.sc.pojo.ums.*;
import com.itheima.sc.utils.AppJwtUtil;
import com.itheima.sc.vo.AdminInfoVo;
import com.itheima.sc.vo.PageResult;
import com.itheima.sc.config.ComException;
import io.jsonwebtoken.Claims;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestParam;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.regex.Pattern;

@Service
public class AdminService {

    @Autowired
    private HttpServletRequest request;

    @DubboReference
    private AdminApi adminApi;
    @Autowired
    private UmsMenuService umsMenuService;
    @Autowired
    private UmsRoleService umsRoleService;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @DubboReference
    private UmsAdminRoleRelationApi umsAdminRoleRelationApi;
    @DubboReference
    private UmsRoleApi umsRoleApi;
    @DubboReference
    private UmsRoleMenuRelationApi umsRoleMenuRelationApi;
    @DubboReference
    private UmsMenuApi umsMenuApi;



    //用户登录
    public Map login(Map<String, String> param) {
        //1.获取数据
        String username = param.get("username");
        String password = DigestUtils.md5DigestAsHex(param.get("password").getBytes());
        //2.通过username远程调用获取数据 用户数据
        Admin admin = adminApi.selectUser(username);

        //判断用户是否存在
        if (ObjectUtil.isEmpty(admin)) {
            // 空
            throw new ComException("用户不存在");
        }

        //3.比较用户的密码
        if (!StrUtil.equals(password, admin.getPassword())) {
            //密码不同
            throw new ComException("用户密码错误");
        }
        //登录成功
        String redisKey = "CHECK_ADMINID";
        stringRedisTemplate.opsForValue().set(redisKey, admin.getId().toString());
        //创建token
        String token = AppJwtUtil.getToken(admin.getId());
        Map map = new HashMap();
        map.put("token", token);
        map.put("tokenHead", "Bearer ");
        return map;
    }

    /**
     * 获取当前登录用户信息
     */
    public AdminInfoVo adminInfo() {
        //获取当前用户的id
        String redisKey = "CHECK_ADMINID";
        String redisId = stringRedisTemplate.opsForValue().get(redisKey);
        Long adminId = Convert.toLong(redisId);

        //根据当前用户的id,获取用户信息
        Admin admin = adminApi.getAdminById(adminId);
        String username = admin.getUsername();
        String icon = admin.getIcon();

        //根据adminId查询roleId
        List<UmsAdminRoleRelation> umsAdminRoleRelations = umsAdminRoleRelationApi.getByAdminId(adminId);
        List<Long> roleIds = CollUtil.getFieldValues(umsAdminRoleRelations, "roleId", Long.class);

        //根据roleIds查询角色
        List<UmsRole> umsRoles = umsRoleApi.getByIds(roleIds);
        List<String> roles = CollUtil.getFieldValues(umsRoles, "name", String.class);

        //根据roleIds查询menus
        List<UmsRoleMenuRelation> umsRoleMenuRelations = umsRoleMenuRelationApi.getByRoleIds(roleIds);
        List<Long> menuIds = CollUtil.getFieldValues(umsRoleMenuRelations, "menuId", Long.class);

        // 根据 menuIds 查询 menus
        List<UmsMenu> menus = umsMenuApi.getByIds(menuIds);

        //封装结果集
        AdminInfoVo adminInfoVo = new AdminInfoVo();
        adminInfoVo.setIcon(icon);
        adminInfoVo.setUsername(username);
        adminInfoVo.setMenus(menus);
        adminInfoVo.setRoles(roles);
        return adminInfoVo;
    }

    /**
     * 根据用户名或姓名分页获取用户列表
     */
    public PageResult list(Integer pageNum, Integer pageSize, String keyword) {
        //调用API进行分页查询,并返回数据
        return adminApi.selectPage(pageNum, pageSize, keyword);
    }

    /**
     * 登出
     */
    public void logout() {
        String redisKey = "CHECK_ADMINID";
        stringRedisTemplate.delete(redisKey);
    }

    /**
     * 刷新token
     */
    public Map<String,Object> refreshToken() {
        //获取当前用户的id
        String redisKey = "CHECK_ADMINID";
        String redisId = stringRedisTemplate.opsForValue().get(redisKey);
        Long adminId = Convert.toLong(redisId);
        String taoken = AppJwtUtil.getToken(adminId);
        Map tokenMap = new HashMap();
        tokenMap.put("token", taoken);
        return tokenMap;
    }

    /**
     * 用户注册
     */
    public Admin register(Admin admin) {
        // 用户名为空,结束,返回错误信息
        if(StringUtils.isEmpty(admin.getUsername())){
            throw new RuntimeException("用户名为空");
        }
        // 密码为空,结束,返回错误信息
        if(StringUtils.isEmpty(admin.getPassword())){
            throw new RuntimeException("请设置密码");
        }
        // 校验邮箱格式,如果格式错误,返回错误信息
        if(StrUtil.isNotEmpty(admin.getEmail())){
            String check = "^(\\w+([-.][A-Za-z0-9]+)*){3,18}@\\w+([-.][A-Za-z0-9]+)*\\.\\w+([-.][A-Za-z0-9]+)*$";
            if(!Pattern.matches(check, admin.getEmail())){
                throw new RuntimeException("邮箱格式错误");
            }
        }
        //封装数据
        admin.setCreateTime(new Date());
        admin.setLoginTime(new Date());
        admin.setStatus(0);
        //调用API注册新用户
        adminApi.register(admin);

        //查询返回值
        return adminApi.selectUser(admin.getUsername());

    }

    /**
     * TODO 给用户分配角色
     */
    public void roleUpdate(Integer[] roleIds, Integer adminId) {
        //先将之前的数据删除
        umsAdminRoleRelationApi.delete(adminId);
        //重新给用户分配角色
        if (ArrayUtil.isNotEmpty(roleIds)) {
            for (Integer roleId : roleIds) {
                UmsAdminRoleRelation umsAdminRoleRelation = new UmsAdminRoleRelation();
                umsAdminRoleRelation.setAdminId(Convert.toLong(adminId));
                umsAdminRoleRelation.setRoleId(Convert.toLong(roleId));
                umsAdminRoleRelationApi.roleUpdate(umsAdminRoleRelation);
            }
        }
    }

    /**
     * 获取指定用户的角色
     */
    public List<UmsRole> specificRole(Integer adminId) {
        //通过adminId获取roleId
        List<UmsAdminRoleRelation> umsAdminRoleRelations = umsAdminRoleRelationApi.getRoleIds(adminId);
        //创建返回值集合
        List<UmsRole> list = new ArrayList<>();
        //遍历集合
        for (UmsAdminRoleRelation umsAdminRoleRelation : umsAdminRoleRelations) {
            //通过roleId获取UmsRole对象
            UmsRole umsRole = umsRoleApi.getUmsRole(umsAdminRoleRelation.getRoleId());
            list.add(umsRole);
        }
        return list;
    }

    /**
     * 修改指定用户信息
     */
    public void update(Admin admin) {
        adminApi.update(admin);
    }

    /**
     * 修改指定用户密码
     */
    public void updatePassword(UpdatePasswordDto updatePasswordDto) {
        //获取前端接收的数据
        String newPassword = updatePasswordDto.getNewPassword();
        String oldPassword = updatePasswordDto.getOldPassword();
        String username = updatePasswordDto.getUsername();

        //调用API,查询用户是否存在
        Admin admin = adminApi.isExit(username, oldPassword);

        if (ObjectUtil.isEmpty(admin)) {
            throw new RuntimeException("用户名或者密码输入错误");
        }

        //重新封装数据
        admin.setPassword(newPassword);

        //调用API.修改数据
        adminApi.update(admin);

    }

    /**
     * 修改账号状态
     */
    public void updateStatus(Integer id, Integer status) {
        adminApi.updateStatus(id, status);
    }

    /**
     * 获取指定用户信息
     */
    public Admin getById(Integer id) {
        return adminApi.selectAdminById(Convert.toLong(id));
    }

    /**
     * 删除指定用户
     */
    public void delete(Integer id) {
        adminApi.delete(id);
    }
}
